{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## neural_network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "training loss:  0.6466875055363447\n",
      "valid loss 0.571338 and accuracy 0.781713 \n",
      "training loss:  0.5270206096687642\n",
      "valid loss 0.454639 and accuracy 0.840203 \n",
      "training loss:  0.4607966051888182\n",
      "valid loss 0.398584 and accuracy 0.867779 \n",
      "training loss:  0.41333284299372364\n",
      "valid loss 0.354675 and accuracy 0.884761 \n",
      "training loss:  0.3760315582463465\n",
      "valid loss 0.316480 and accuracy 0.908926 \n",
      "training loss:  0.3447422012610256\n",
      "valid loss 0.288969 and accuracy 0.922569 \n",
      "training loss:  0.3190244728377965\n",
      "valid loss 0.265451 and accuracy 0.930261 \n",
      "training loss:  0.29830814337720024\n",
      "valid loss 0.241914 and accuracy 0.937300 \n",
      "training loss:  0.27680253226292983\n",
      "valid loss 0.227495 and accuracy 0.941001 \n",
      "training loss:  0.2612551061675165\n",
      "valid loss 0.210494 and accuracy 0.944630 \n",
      "training loss:  0.24494338234692042\n",
      "valid loss 0.201078 and accuracy 0.945573 \n",
      "training loss:  0.23475687898453768\n",
      "valid loss 0.190259 and accuracy 0.949492 \n",
      "training loss:  0.22149084202016198\n",
      "valid loss 0.181957 and accuracy 0.950871 \n",
      "training loss:  0.21174219796327273\n",
      "valid loss 0.173665 and accuracy 0.953193 \n",
      "training loss:  0.20421914887090503\n",
      "valid loss 0.162425 and accuracy 0.957475 \n",
      "training loss:  0.19443732116783075\n",
      "valid loss 0.156672 and accuracy 0.958200 \n",
      "training loss:  0.18735587008883506\n",
      "valid loss 0.150185 and accuracy 0.959434 \n",
      "training loss:  0.17921015629501114\n",
      "valid loss 0.142043 and accuracy 0.960813 \n",
      "training loss:  0.1744929809973869\n",
      "valid loss 0.137564 and accuracy 0.961103 \n",
      "training loss:  0.17094286493830746\n",
      "valid loss 0.131370 and accuracy 0.964296 \n",
      "training loss:  0.16552978166589943\n",
      "valid loss 0.134240 and accuracy 0.962700 \n",
      "training loss:  0.158821182880319\n",
      "valid loss 0.125791 and accuracy 0.965022 \n",
      "training loss:  0.1571957594671463\n",
      "valid loss 0.122143 and accuracy 0.966909 \n",
      "training loss:  0.15372752327039665\n",
      "valid loss 0.120320 and accuracy 0.964514 \n",
      "training loss:  0.14812637133207673\n",
      "valid loss 0.115795 and accuracy 0.968360 \n",
      "training loss:  0.14888640707951675\n",
      "valid loss 0.114315 and accuracy 0.966981 \n",
      "training loss:  0.14318896372076667\n",
      "valid loss 0.112097 and accuracy 0.968723 \n",
      "training loss:  0.1425953336202102\n",
      "valid loss 0.108739 and accuracy 0.969303 \n",
      "training loss:  0.13740535816476376\n",
      "valid loss 0.105890 and accuracy 0.969448 \n",
      "training loss:  0.1347934880839444\n",
      "valid loss 0.102938 and accuracy 0.971408 \n",
      "training loss:  0.13349996185238588\n",
      "valid loss 0.101689 and accuracy 0.971916 \n",
      "training loss:  0.1305648884773514\n",
      "valid loss 0.099910 and accuracy 0.971626 \n",
      "training loss:  0.13188047213480744\n",
      "valid loss 0.100723 and accuracy 0.971626 \n",
      "training loss:  0.12607309093491398\n",
      "valid loss 0.098608 and accuracy 0.970900 \n",
      "training loss:  0.12617479391287825\n",
      "valid loss 0.096309 and accuracy 0.972424 \n",
      "training loss:  0.12388834458971086\n",
      "valid loss 0.096230 and accuracy 0.972496 \n",
      "training loss:  0.12102771736826297\n",
      "valid loss 0.095400 and accuracy 0.971626 \n",
      "training loss:  0.1196649155792213\n",
      "valid loss 0.094451 and accuracy 0.971916 \n",
      "training loss:  0.12133585394758047\n",
      "valid loss 0.093547 and accuracy 0.971480 \n",
      "training loss:  0.11811969161204189\n",
      "valid loss 0.092170 and accuracy 0.971408 \n",
      "training loss:  0.11576538122450003\n",
      "valid loss 0.090757 and accuracy 0.972787 \n",
      "training loss:  0.11589630721816786\n",
      "valid loss 0.089459 and accuracy 0.973512 \n",
      "training loss:  0.11414883594179831\n",
      "valid loss 0.087766 and accuracy 0.975036 \n",
      "training loss:  0.11124469670084568\n",
      "valid loss 0.087772 and accuracy 0.974238 \n",
      "training loss:  0.10951109613788387\n",
      "valid loss 0.086057 and accuracy 0.974673 \n",
      "training loss:  0.10617788554383624\n",
      "valid loss 0.086919 and accuracy 0.975036 \n",
      "training loss:  0.10490308735640266\n",
      "valid loss 0.084705 and accuracy 0.975254 \n",
      "training loss:  0.10622971473155521\n",
      "valid loss 0.083198 and accuracy 0.974819 \n",
      "training loss:  0.10223183388392226\n",
      "valid loss 0.082725 and accuracy 0.974819 \n",
      "training loss:  0.10340799066884043\n",
      "valid loss 0.084467 and accuracy 0.974601 \n",
      "training loss:  0.10354254056711537\n",
      "valid loss 0.084400 and accuracy 0.975762 \n",
      "training loss:  0.10282867393055466\n",
      "valid loss 0.081376 and accuracy 0.975689 \n",
      "training loss:  0.10167572280748173\n",
      "valid loss 0.085421 and accuracy 0.973149 \n",
      "training loss:  0.09952388848102629\n",
      "valid loss 0.081950 and accuracy 0.974383 \n",
      "training loss:  0.0984633588447181\n",
      "valid loss 0.079113 and accuracy 0.975689 \n",
      "training loss:  0.097352120232667\n",
      "valid loss 0.081565 and accuracy 0.974891 \n",
      "training loss:  0.09836929676378946\n",
      "valid loss 0.078469 and accuracy 0.976851 \n",
      "training loss:  0.0945218943764157\n",
      "valid loss 0.082739 and accuracy 0.971553 \n",
      "training loss:  0.09527045058763245\n",
      "valid loss 0.078304 and accuracy 0.977213 \n",
      "training loss:  0.09761373715998986\n",
      "valid loss 0.076560 and accuracy 0.978374 \n",
      "training loss:  0.09714557521140452\n",
      "valid loss 0.077673 and accuracy 0.975907 \n",
      "training loss:  0.09259868831217358\n",
      "valid loss 0.078929 and accuracy 0.974819 \n",
      "training loss:  0.09129912956883082\n",
      "valid loss 0.081913 and accuracy 0.971626 \n",
      "training loss:  0.09279434109233942\n",
      "valid loss 0.073592 and accuracy 0.977286 \n",
      "training loss:  0.09396537199900543\n",
      "valid loss 0.080904 and accuracy 0.972134 \n",
      "training loss:  0.09117551083653894\n",
      "valid loss 0.073798 and accuracy 0.978012 \n",
      "training loss:  0.09217027695999298\n",
      "valid loss 0.074158 and accuracy 0.978810 \n",
      "training loss:  0.0913807854757595\n",
      "valid loss 0.081631 and accuracy 0.972061 \n",
      "training loss:  0.09273112978396796\n",
      "valid loss 0.081273 and accuracy 0.971698 \n",
      "training loss:  0.0891773037422182\n",
      "valid loss 0.076372 and accuracy 0.973222 \n",
      "training loss:  0.08949099194099364\n",
      "valid loss 0.073597 and accuracy 0.978737 \n",
      "training loss:  0.08708936836792854\n",
      "valid loss 0.072124 and accuracy 0.980044 \n",
      "training loss:  0.08585799945674971\n",
      "valid loss 0.072298 and accuracy 0.977649 \n",
      "training loss:  0.08759459977290711\n",
      "valid loss 0.071187 and accuracy 0.978084 \n",
      "training loss:  0.08406136725504014\n",
      "valid loss 0.071453 and accuracy 0.978012 \n",
      "training loss:  0.0842426643186869\n",
      "valid loss 0.073936 and accuracy 0.977068 \n",
      "training loss:  0.0859955175441163\n",
      "valid loss 0.068875 and accuracy 0.979608 \n",
      "training loss:  0.08523331814839537\n",
      "valid loss 0.071240 and accuracy 0.977504 \n",
      "training loss:  0.08633235394296548\n",
      "valid loss 0.078412 and accuracy 0.973803 \n",
      "training loss:  0.08263392709370575\n",
      "valid loss 0.069363 and accuracy 0.981495 \n",
      "training loss:  0.08153687286969644\n",
      "valid loss 0.067450 and accuracy 0.981422 \n",
      "training loss:  0.08066233817777278\n",
      "valid loss 0.067362 and accuracy 0.981422 \n",
      "training loss:  0.07797649733854069\n",
      "valid loss 0.066677 and accuracy 0.982366 \n",
      "training loss:  0.07879194533776535\n",
      "valid loss 0.069682 and accuracy 0.976633 \n",
      "training loss:  0.07663844899316383\n",
      "valid loss 0.065303 and accuracy 0.981567 \n",
      "training loss:  0.0761473098052152\n",
      "valid loss 0.063132 and accuracy 0.982946 \n",
      "training loss:  0.07577501800096534\n",
      "valid loss 0.061414 and accuracy 0.981495 \n",
      "training loss:  0.0761592366497241\n",
      "valid loss 0.064599 and accuracy 0.980406 \n",
      "training loss:  0.0739567139772289\n",
      "valid loss 0.061761 and accuracy 0.982293 \n",
      "training loss:  0.07218637086747909\n",
      "valid loss 0.061237 and accuracy 0.983019 \n",
      "training loss:  0.07180799998896611\n",
      "valid loss 0.059374 and accuracy 0.982874 \n",
      "training loss:  0.07040853704084007\n",
      "valid loss 0.059006 and accuracy 0.984906 \n",
      "training loss:  0.07216710998123996\n",
      "valid loss 0.059496 and accuracy 0.984761 \n",
      "training loss:  0.07126230499093493\n",
      "valid loss 0.057999 and accuracy 0.984398 \n",
      "training loss:  0.07215211764480874\n",
      "valid loss 0.056470 and accuracy 0.983237 \n",
      "training loss:  0.06841539048405332\n",
      "valid loss 0.056332 and accuracy 0.984906 \n",
      "training loss:  0.06804760067592268\n",
      "valid loss 0.057449 and accuracy 0.981567 \n",
      "training loss:  0.0672433428290895\n",
      "valid loss 0.061603 and accuracy 0.979390 \n",
      "training loss:  0.06435033085182078\n",
      "valid loss 0.056700 and accuracy 0.982075 \n",
      "training loss:  0.06427118029641343\n",
      "valid loss 0.051892 and accuracy 0.986430 \n",
      "training loss:  0.06420179519226812\n",
      "valid loss 0.053724 and accuracy 0.987010 \n",
      "training loss:  0.06326249368253112\n",
      "valid loss 0.053812 and accuracy 0.985631 \n",
      "training loss:  0.06397375479803565\n",
      "valid loss 0.056331 and accuracy 0.986212 \n",
      "training loss:  0.06378250423087581\n",
      "valid loss 0.052020 and accuracy 0.987446 \n",
      "training loss:  0.062639300565951\n",
      "valid loss 0.054304 and accuracy 0.983672 \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "training loss:  0.06181763427661168\n",
      "valid loss 0.054994 and accuracy 0.982729 \n",
      "training loss:  0.0611133094422684\n",
      "valid loss 0.052337 and accuracy 0.984906 \n",
      "training loss:  0.05861138408176719\n",
      "valid loss 0.051243 and accuracy 0.984107 \n",
      "training loss:  0.05951001420503552\n",
      "valid loss 0.052292 and accuracy 0.986647 \n",
      "training loss:  0.06032081228221751\n",
      "valid loss 0.055115 and accuracy 0.983019 \n",
      "training loss:  0.06010699561688137\n",
      "valid loss 0.055900 and accuracy 0.982148 \n",
      "training loss:  0.05699296689665502\n",
      "valid loss 0.048643 and accuracy 0.987808 \n",
      "training loss:  0.05898426991490338\n",
      "valid loss 0.051376 and accuracy 0.988607 \n",
      "training loss:  0.05886859940479956\n",
      "valid loss 0.048817 and accuracy 0.987010 \n",
      "training loss:  0.0592263220765341\n",
      "valid loss 0.047968 and accuracy 0.986720 \n",
      "training loss:  0.05630592988865219\n",
      "valid loss 0.047443 and accuracy 0.986720 \n",
      "training loss:  0.05689762032089298\n",
      "valid loss 0.048300 and accuracy 0.988316 \n",
      "training loss:  0.05790912573498696\n",
      "valid loss 0.049748 and accuracy 0.985269 \n",
      "training loss:  0.056852478877997006\n",
      "valid loss 0.047716 and accuracy 0.987300 \n",
      "training loss:  0.05640984287680777\n",
      "valid loss 0.047648 and accuracy 0.988679 \n",
      "training loss:  0.056482601007518195\n",
      "valid loss 0.047776 and accuracy 0.986720 \n",
      "training loss:  0.05414409068163411\n",
      "valid loss 0.050210 and accuracy 0.984906 \n",
      "training loss:  0.05496723351401714\n",
      "valid loss 0.046003 and accuracy 0.987373 \n",
      "training loss:  0.05345376568254403\n",
      "valid loss 0.046614 and accuracy 0.989623 \n",
      "training loss:  0.05319216272503083\n",
      "valid loss 0.053928 and accuracy 0.985051 \n",
      "training loss:  0.05521533320249211\n",
      "valid loss 0.049249 and accuracy 0.986067 \n",
      "training loss:  0.05704410105581243\n",
      "valid loss 0.056230 and accuracy 0.983599 \n",
      "training loss:  0.05373189783804317\n",
      "valid loss 0.046600 and accuracy 0.987954 \n",
      "training loss:  0.0530149755828366\n",
      "valid loss 0.049471 and accuracy 0.985631 \n",
      "training loss:  0.05262526237849874\n",
      "valid loss 0.055371 and accuracy 0.985486 \n",
      "training loss:  0.055425241262217505\n",
      "valid loss 0.043005 and accuracy 0.990276 \n",
      "training loss:  0.05180798811673903\n",
      "valid loss 0.044141 and accuracy 0.989913 \n",
      "training loss:  0.05163913770890459\n",
      "valid loss 0.047507 and accuracy 0.989985 \n",
      "training loss:  0.05133894830548201\n",
      "valid loss 0.051045 and accuracy 0.985631 \n",
      "training loss:  0.05287711574089983\n",
      "valid loss 0.044035 and accuracy 0.989695 \n",
      "training loss:  0.04938751151884612\n",
      "valid loss 0.051485 and accuracy 0.985486 \n",
      "training loss:  0.05152733389880623\n",
      "valid loss 0.049464 and accuracy 0.986357 \n",
      "training loss:  0.05090391799188347\n",
      "valid loss 0.043403 and accuracy 0.991292 \n",
      "training loss:  0.05136460603622455\n",
      "valid loss 0.044392 and accuracy 0.989405 \n",
      "training loss:  0.05110153093763037\n",
      "valid loss 0.042574 and accuracy 0.991219 \n",
      "training loss:  0.05191354271001176\n",
      "valid loss 0.046520 and accuracy 0.987083 \n",
      "training loss:  0.049703274233022406\n",
      "valid loss 0.047879 and accuracy 0.987083 \n",
      "training loss:  0.04986272312111904\n",
      "valid loss 0.045263 and accuracy 0.988316 \n",
      "training loss:  0.04944910820904837\n",
      "valid loss 0.044115 and accuracy 0.988897 \n",
      "training loss:  0.048754552417429216\n",
      "valid loss 0.044856 and accuracy 0.990276 \n",
      "training loss:  0.05153198445279607\n",
      "valid loss 0.042952 and accuracy 0.991582 \n",
      "training loss:  0.05050016925272343\n",
      "valid loss 0.043920 and accuracy 0.991364 \n",
      "training loss:  0.05090268091510245\n",
      "valid loss 0.045497 and accuracy 0.989332 \n",
      "training loss:  0.0501518741244013\n",
      "valid loss 0.049784 and accuracy 0.986502 \n",
      "training loss:  0.04975211437733536\n",
      "valid loss 0.049005 and accuracy 0.985776 \n",
      "training loss:  0.052238168810210046\n",
      "valid loss 0.045669 and accuracy 0.987591 \n",
      "training loss:  0.047568605774288515\n",
      "valid loss 0.041253 and accuracy 0.991582 \n",
      "training loss:  0.048231784590678964\n",
      "valid loss 0.043716 and accuracy 0.990856 \n",
      "training loss:  0.04989269866168449\n",
      "valid loss 0.047589 and accuracy 0.987446 \n",
      "training loss:  0.04788244842626934\n",
      "valid loss 0.041703 and accuracy 0.990639 \n",
      "training loss:  0.04915750308889189\n",
      "valid loss 0.043405 and accuracy 0.991001 \n",
      "training loss:  0.047734555723249014\n",
      "valid loss 0.046683 and accuracy 0.987300 \n",
      "training loss:  0.05064857657393387\n",
      "valid loss 0.043510 and accuracy 0.991147 \n",
      "training loss:  0.04919566859310327\n",
      "valid loss 0.043821 and accuracy 0.990421 \n",
      "training loss:  0.049656396057784755\n",
      "valid loss 0.042451 and accuracy 0.992235 \n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from collections import Counter\n",
    "from sklearn.model_selection import train_test_split\n",
    "import torch\n",
    "from torch.utils.data import Dataset,DataLoader\n",
    "import torch.optim as torch_optim\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torchvision import models\n",
    "from datetime import datetime\n",
    "import pandas_profiling as ppf\n",
    "from tensorboardX import SummaryWriter\n",
    "writer=SummaryWriter(logdir='./neuron')\n",
    "\n",
    "ALL=pd.read_csv(r'./data/created_data/logistic_final.csv').reset_index(drop=True).set_index('ID')\n",
    "\n",
    "y=ALL['flag'].to_numpy()\n",
    "train_X,val_X, train_y, val_y = train_test_split(ALL.drop(columns='flag'),y, test_size=0.30, random_state=0)\n",
    "\n",
    "class CompanyDataset(Dataset):\n",
    "    def __init__(self, X, Y):\n",
    "\n",
    "        self.x = X.copy().values.astype(np.float32)\n",
    "        self.y = Y\n",
    "        \n",
    "    def __len__(self):\n",
    "        return len(self.y)\n",
    "    \n",
    "    def __getitem__(self, idx):\n",
    "\n",
    "        return self.x[idx],self.y[idx]\n",
    "\n",
    "train_ds = CompanyDataset(train_X, train_y,)#embedded_col_names\n",
    "valid_ds = CompanyDataset(val_X,val_y,)#embedded_col_names\n",
    "\n",
    "def get_default_device():\n",
    "    \"\"\"Pick GPU if available, else CPU\"\"\"\n",
    "    if torch.cuda.is_available():\n",
    "        return torch.device('cuda')\n",
    "    else:\n",
    "        return torch.device('cpu')\n",
    "    \n",
    "def to_device(data, device):\n",
    "    \"\"\"Move tensor(s) to chosen device\"\"\"\n",
    "    if isinstance(data, (list,tuple)):\n",
    "        return [to_device(x, device) for x in data]\n",
    "    return data.to(device, non_blocking=True)\n",
    "\n",
    "class DeviceDataLoader():\n",
    "    \"\"\"Wrap a dataloader to move data to a device\"\"\"\n",
    "    def __init__(self, dl, device):\n",
    "        self.dl = dl\n",
    "        self.device = device\n",
    "        \n",
    "    def __iter__(self):\n",
    "        \"\"\"Yield a batch of data after moving it to device\"\"\"\n",
    "        for b in self.dl: \n",
    "            yield to_device(b, self.device)\n",
    "\n",
    "    def __len__(self):\n",
    "        \"\"\"Number of batches\"\"\"\n",
    "        return len(self.dl)\n",
    "device = get_default_device()\n",
    "\n",
    "class FlagModel(nn.Module): \n",
    "    def __init__(self,n):\n",
    "        super().__init__()\n",
    "     \n",
    "        self.lin1 = nn.Linear(n, 200)  \n",
    "        self.lin2 = nn.Linear(200, 70)\n",
    "        self.lin3 = nn.Linear(70, 2)\n",
    "\n",
    "        self.bn2 = nn.BatchNorm1d(200)\n",
    "        self.bn3 = nn.BatchNorm1d(70)\n",
    "        \n",
    "\n",
    "        self.drops = nn.Dropout(0.3)\n",
    "        \n",
    "\n",
    "    def forward(self,x): \n",
    "\n",
    "        x = F.relu(self.lin1(x))  #线性层并激活\n",
    "        x = self.drops(x)        #drop_out\n",
    "        \n",
    "        x = self.bn2(x)         #标准化\n",
    "        x = F.relu(self.lin2(x)) #线性层并激活\n",
    "        x = self.drops(x)        #drop_out\n",
    "        x = self.bn3(x)          #标准化\n",
    "        x = self.lin3(x)         #线性层\n",
    "#         x=torch.sigmoid(x)\n",
    "        return x\n",
    "\n",
    "model = FlagModel(12)\n",
    "to_device(model, device)\n",
    "\n",
    "def get_optimizer(model, lr = 0.001, wd = 0.0):\n",
    "    parameters = filter(lambda p: p.requires_grad, model.parameters()) #filter过滤序列，留下True\n",
    "    optim = torch_optim.Adam(parameters, lr=lr, weight_decay=wd)\n",
    "    return optim\n",
    "\n",
    "def train_model(model, optim, train_dl,i):\n",
    "    model.train()\n",
    "    total = 0\n",
    "    sum_loss = 0\n",
    "    for x1, y in train_dl:\n",
    "        batch = y.shape[0]\n",
    "        output = model(x1)\n",
    "        y=y.long()\n",
    "        loss = F.cross_entropy(output, y)   \n",
    "        optim.zero_grad()\n",
    "        loss.backward()\n",
    "        optim.step()\n",
    "        total += batch\n",
    "        sum_loss += batch*(loss.item())\n",
    "    writer.add_scalar('train_loss',sum_loss/total,i)\n",
    "    return sum_loss/total\n",
    "def val_loss(model, valid_dl,i):\n",
    "    model.eval()\n",
    "    total = 0\n",
    "    sum_loss = 0\n",
    "    correct = 0\n",
    "    for x1,y in valid_dl:\n",
    "        current_batch_size = y.shape[0]\n",
    "        out = model(x1)\n",
    "        y=y.long()\n",
    "        loss = F.cross_entropy(out, y)\n",
    "        sum_loss += current_batch_size*(loss.item())\n",
    "        total += current_batch_size\n",
    "        pred = torch.max(out, 1)[1]\n",
    "        correct += (pred == y).float().sum().item()\n",
    "#         correct = torch.mean((pred == y).float())\n",
    "    writer.add_scalar('valid_loss',sum_loss/total,i)\n",
    "    writer.add_scalar('valid_acc',correct/total,i)\n",
    "    print(\"valid loss %f and accuracy %f \" % (sum_loss/total, correct/total))\n",
    "    return sum_loss/total, correct/total\n",
    "\n",
    "def train_loop(model, epochs, lr=0.01, wd=0.0):\n",
    "    optim = get_optimizer(model, lr = lr, wd = wd)\n",
    "    for i in range(epochs): \n",
    "        loss = train_model(model, optim, train_dl,i)\n",
    "        print(\"training loss: \", loss)\n",
    "        _,acc=val_loss(model, valid_dl,i)\n",
    "        if acc>0.992:\n",
    "            break\n",
    "    return \n",
    "batch_size = 1000\n",
    "train_dl = DataLoader(train_ds, batch_size=batch_size,shuffle=True)\n",
    "valid_dl = DataLoader(valid_ds, batch_size=batch_size,shuffle=True)\n",
    "train_dl = DeviceDataLoader(train_dl,device)\n",
    "valid_dl = DeviceDataLoader(valid_dl,device)\n",
    "train_loop(model, epochs=1000, lr=0.0001, wd=0.05)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "for x1,y in valid_dl:\n",
    "    break\n",
    "writer.add_graph(model,(x1,))\n",
    "writer.close()\n",
    "torch.save(model.state_dict(), \"p99383p.npy\")\n",
    "# model.load_state_dict(torch.load(\"p99383p.npy\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "writer.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## logistic regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch:100,Loss:0.3896,Accuracy：0.9693\n",
      "Epoch:200,Loss:0.3743,Accuracy：0.9673\n",
      "Epoch:300,Loss:0.3664,Accuracy：0.9687\n",
      "Epoch:400,Loss:0.3615,Accuracy：0.9689\n",
      "Epoch:500,Loss:0.3580,Accuracy：0.9702\n",
      "Epoch:600,Loss:0.3553,Accuracy：0.9710\n",
      "Epoch:700,Loss:0.3532,Accuracy：0.9720\n",
      "Epoch:800,Loss:0.3515,Accuracy：0.9722\n",
      "Epoch:900,Loss:0.3500,Accuracy：0.9728\n",
      "Epoch:1000,Loss:0.3488,Accuracy：0.9736\n",
      "Epoch:1100,Loss:0.3477,Accuracy：0.9738\n",
      "Epoch:1200,Loss:0.3468,Accuracy：0.9741\n",
      "Epoch:1300,Loss:0.3459,Accuracy：0.9745\n",
      "Epoch:1400,Loss:0.3452,Accuracy：0.9747\n",
      "Epoch:1500,Loss:0.3445,Accuracy：0.9748\n",
      "Epoch:1600,Loss:0.3438,Accuracy：0.9753\n",
      "Epoch:1700,Loss:0.3433,Accuracy：0.9757\n",
      "Epoch:1800,Loss:0.3427,Accuracy：0.9758\n",
      "Epoch:1900,Loss:0.3422,Accuracy：0.9761\n",
      "Epoch:2000,Loss:0.3417,Accuracy：0.9763\n",
      "Epoch:2100,Loss:0.3413,Accuracy：0.9763\n",
      "Epoch:2200,Loss:0.3408,Accuracy：0.9764\n",
      "Epoch:2300,Loss:0.3404,Accuracy：0.9766\n",
      "Epoch:2400,Loss:0.3400,Accuracy：0.9769\n",
      "Epoch:2500,Loss:0.3397,Accuracy：0.9769\n",
      "Epoch:2600,Loss:0.3393,Accuracy：0.9771\n",
      "Epoch:2700,Loss:0.3390,Accuracy：0.9773\n",
      "Epoch:2800,Loss:0.3387,Accuracy：0.9774\n",
      "Epoch:2900,Loss:0.3384,Accuracy：0.9776\n",
      "Epoch:3000,Loss:0.3381,Accuracy：0.9778\n",
      "Epoch:3100,Loss:0.3378,Accuracy：0.9778\n",
      "Epoch:3200,Loss:0.3375,Accuracy：0.9780\n",
      "Epoch:3300,Loss:0.3373,Accuracy：0.9781\n",
      "Epoch:3400,Loss:0.3370,Accuracy：0.9782\n",
      "Epoch:3500,Loss:0.3368,Accuracy：0.9787\n",
      "Epoch:3600,Loss:0.3365,Accuracy：0.9791\n",
      "Epoch:3700,Loss:0.3363,Accuracy：0.9795\n",
      "Epoch:3800,Loss:0.3361,Accuracy：0.9798\n",
      "Epoch:3900,Loss:0.3358,Accuracy：0.9798\n",
      "Epoch:4000,Loss:0.3356,Accuracy：0.9800\n",
      "Epoch:4100,Loss:0.3354,Accuracy：0.9801\n",
      "Epoch:4200,Loss:0.3352,Accuracy：0.9803\n",
      "Epoch:4300,Loss:0.3350,Accuracy：0.9804\n",
      "Epoch:4400,Loss:0.3348,Accuracy：0.9806\n",
      "Epoch:4500,Loss:0.3347,Accuracy：0.9807\n",
      "Epoch:4600,Loss:0.3345,Accuracy：0.9808\n",
      "Epoch:4700,Loss:0.3343,Accuracy：0.9811\n",
      "Epoch:4800,Loss:0.3341,Accuracy：0.9811\n",
      "Epoch:4900,Loss:0.3340,Accuracy：0.9813\n",
      "Epoch:5000,Loss:0.3338,Accuracy：0.9813\n",
      "Epoch:5100,Loss:0.3336,Accuracy：0.9814\n",
      "Epoch:5200,Loss:0.3335,Accuracy：0.9816\n",
      "Epoch:5300,Loss:0.3333,Accuracy：0.9820\n",
      "Epoch:5400,Loss:0.3332,Accuracy：0.9820\n",
      "Epoch:5500,Loss:0.3331,Accuracy：0.9819\n",
      "Epoch:5600,Loss:0.3329,Accuracy：0.9823\n",
      "Epoch:5700,Loss:0.3328,Accuracy：0.9832\n",
      "Epoch:5800,Loss:0.3326,Accuracy：0.9827\n",
      "Epoch:5900,Loss:0.3325,Accuracy：0.9828\n",
      "Epoch:6000,Loss:0.3324,Accuracy：0.9829\n",
      "Epoch:6100,Loss:0.3323,Accuracy：0.9830\n",
      "Epoch:6200,Loss:0.3321,Accuracy：0.9830\n",
      "Epoch:6300,Loss:0.3320,Accuracy：0.9829\n",
      "Epoch:6400,Loss:0.3319,Accuracy：0.9829\n",
      "Epoch:6500,Loss:0.3318,Accuracy：0.9830\n",
      "Epoch:6600,Loss:0.3317,Accuracy：0.9835\n",
      "Epoch:6700,Loss:0.3316,Accuracy：0.9835\n",
      "Epoch:6800,Loss:0.3315,Accuracy：0.9836\n",
      "Epoch:6900,Loss:0.3314,Accuracy：0.9835\n",
      "Epoch:7000,Loss:0.3313,Accuracy：0.9838\n",
      "Epoch:7100,Loss:0.3313,Accuracy：0.9842\n",
      "Epoch:7200,Loss:0.3311,Accuracy：0.9839\n",
      "Epoch:7300,Loss:0.3311,Accuracy：0.9844\n",
      "Epoch:7400,Loss:0.3310,Accuracy：0.9842\n",
      "Epoch:7500,Loss:0.3309,Accuracy：0.9843\n",
      "Epoch:7600,Loss:0.3308,Accuracy：0.9845\n",
      "Epoch:7700,Loss:0.3307,Accuracy：0.9845\n",
      "Epoch:7800,Loss:0.3306,Accuracy：0.9845\n",
      "Epoch:7900,Loss:0.3306,Accuracy：0.9848\n",
      "Epoch:8000,Loss:0.3305,Accuracy：0.9840\n",
      "Epoch:8100,Loss:0.3304,Accuracy：0.9848\n",
      "Epoch:8200,Loss:0.3304,Accuracy：0.9850\n",
      "Epoch:8300,Loss:0.3303,Accuracy：0.9850\n",
      "Epoch:8400,Loss:0.3302,Accuracy：0.9850\n",
      "Epoch:8500,Loss:0.3302,Accuracy：0.9851\n",
      "Epoch:8600,Loss:0.3301,Accuracy：0.9851\n",
      "Epoch:8700,Loss:0.3300,Accuracy：0.9851\n",
      "Epoch:8800,Loss:0.3300,Accuracy：0.9851\n",
      "Epoch:8900,Loss:0.3299,Accuracy：0.9851\n",
      "Epoch:9000,Loss:0.3299,Accuracy：0.9851\n",
      "Epoch:9100,Loss:0.3298,Accuracy：0.9851\n",
      "Epoch:9200,Loss:0.3298,Accuracy：0.9851\n",
      "Epoch:9300,Loss:0.3297,Accuracy：0.9851\n",
      "Epoch:9400,Loss:0.3297,Accuracy：0.9851\n",
      "Epoch:9500,Loss:0.3296,Accuracy：0.9852\n",
      "Epoch:9600,Loss:0.3296,Accuracy：0.9851\n",
      "Epoch:9700,Loss:0.3295,Accuracy：0.9853\n",
      "Epoch:9800,Loss:0.3295,Accuracy：0.9853\n",
      "Epoch:9900,Loss:0.3295,Accuracy：0.9853\n",
      "Epoch:10000,Loss:0.3294,Accuracy：0.9853\n",
      "Epoch:10100,Loss:0.3294,Accuracy：0.9852\n",
      "Epoch:10200,Loss:0.3293,Accuracy：0.9853\n",
      "Epoch:10300,Loss:0.3293,Accuracy：0.9850\n",
      "Epoch:10400,Loss:0.3293,Accuracy：0.9853\n",
      "Epoch:10500,Loss:0.3292,Accuracy：0.9853\n",
      "Epoch:10600,Loss:0.3292,Accuracy：0.9853\n",
      "Epoch:10700,Loss:0.3292,Accuracy：0.9853\n",
      "Epoch:10800,Loss:0.3291,Accuracy：0.9854\n",
      "Epoch:10900,Loss:0.3291,Accuracy：0.9854\n",
      "Epoch:11000,Loss:0.3291,Accuracy：0.9855\n",
      "Epoch:11100,Loss:0.3290,Accuracy：0.9856\n",
      "Epoch:11200,Loss:0.3290,Accuracy：0.9856\n",
      "Epoch:11300,Loss:0.3290,Accuracy：0.9856\n",
      "Epoch:11400,Loss:0.3290,Accuracy：0.9856\n",
      "Epoch:11500,Loss:0.3289,Accuracy：0.9856\n",
      "Epoch:11600,Loss:0.3289,Accuracy：0.9856\n",
      "Epoch:11700,Loss:0.3289,Accuracy：0.9857\n",
      "Epoch:11800,Loss:0.3289,Accuracy：0.9860\n",
      "Epoch:11900,Loss:0.3288,Accuracy：0.9858\n",
      "Epoch:12000,Loss:0.3288,Accuracy：0.9853\n",
      "Epoch:12100,Loss:0.3288,Accuracy：0.9858\n",
      "Epoch:12200,Loss:0.3288,Accuracy：0.9860\n",
      "Epoch:12300,Loss:0.3288,Accuracy：0.9858\n",
      "Epoch:12400,Loss:0.3287,Accuracy：0.9859\n",
      "Epoch:12500,Loss:0.3287,Accuracy：0.9859\n",
      "Epoch:12600,Loss:0.3287,Accuracy：0.9859\n",
      "Epoch:12700,Loss:0.3287,Accuracy：0.9859\n",
      "Epoch:12800,Loss:0.3287,Accuracy：0.9860\n",
      "Epoch:12900,Loss:0.3286,Accuracy：0.9860\n",
      "Epoch:13000,Loss:0.3286,Accuracy：0.9860\n",
      "Epoch:13100,Loss:0.3286,Accuracy：0.9860\n",
      "Epoch:13200,Loss:0.3286,Accuracy：0.9860\n",
      "Epoch:13300,Loss:0.3286,Accuracy：0.9860\n",
      "Epoch:13400,Loss:0.3286,Accuracy：0.9860\n",
      "Epoch:13500,Loss:0.3285,Accuracy：0.9860\n",
      "Epoch:13600,Loss:0.3285,Accuracy：0.9860\n",
      "Epoch:13700,Loss:0.3285,Accuracy：0.9860\n",
      "Epoch:13800,Loss:0.3285,Accuracy：0.9860\n",
      "Epoch:13900,Loss:0.3285,Accuracy：0.9860\n",
      "Epoch:14000,Loss:0.3285,Accuracy：0.9860\n",
      "Epoch:14100,Loss:0.3284,Accuracy：0.9860\n",
      "Epoch:14200,Loss:0.3284,Accuracy：0.9858\n",
      "Epoch:14300,Loss:0.3284,Accuracy：0.9860\n",
      "Epoch:14400,Loss:0.3284,Accuracy：0.9860\n",
      "Epoch:14500,Loss:0.3284,Accuracy：0.9861\n",
      "Epoch:14600,Loss:0.3284,Accuracy：0.9861\n",
      "Epoch:14700,Loss:0.3284,Accuracy：0.9861\n",
      "Epoch:14800,Loss:0.3284,Accuracy：0.9861\n",
      "Epoch:14900,Loss:0.3284,Accuracy：0.9861\n",
      "Epoch:15000,Loss:0.3283,Accuracy：0.9861\n",
      "Epoch:15100,Loss:0.3283,Accuracy：0.9861\n",
      "Epoch:15200,Loss:0.3283,Accuracy：0.9861\n",
      "Epoch:15300,Loss:0.3283,Accuracy：0.9861\n",
      "Epoch:15400,Loss:0.3283,Accuracy：0.9861\n",
      "Epoch:15500,Loss:0.3283,Accuracy：0.9861\n",
      "Epoch:15600,Loss:0.3283,Accuracy：0.9863\n",
      "Epoch:15700,Loss:0.3283,Accuracy：0.9861\n",
      "Epoch:15800,Loss:0.3283,Accuracy：0.9862\n",
      "Epoch:15900,Loss:0.3282,Accuracy：0.9862\n",
      "Epoch:16000,Loss:0.3282,Accuracy：0.9863\n",
      "Epoch:16100,Loss:0.3282,Accuracy：0.9863\n",
      "Epoch:16200,Loss:0.3282,Accuracy：0.9863\n",
      "Epoch:16300,Loss:0.3282,Accuracy：0.9862\n",
      "Epoch:16400,Loss:0.3282,Accuracy：0.9861\n",
      "Epoch:16500,Loss:0.3282,Accuracy：0.9862\n",
      "Epoch:16600,Loss:0.3282,Accuracy：0.9863\n",
      "Epoch:16700,Loss:0.3282,Accuracy：0.9862\n",
      "Epoch:16800,Loss:0.3282,Accuracy：0.9862\n",
      "Epoch:16900,Loss:0.3282,Accuracy：0.9863\n",
      "Epoch:17000,Loss:0.3282,Accuracy：0.9862\n",
      "Epoch:17100,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:17200,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:17300,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:17400,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:17500,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:17600,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:17700,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:17800,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:17900,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:18000,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:18100,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:18200,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:18300,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:18400,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:18500,Loss:0.3281,Accuracy：0.9861\n",
      "Epoch:18600,Loss:0.3281,Accuracy：0.9862\n",
      "Epoch:18700,Loss:0.3280,Accuracy：0.9861\n",
      "Epoch:18800,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:18900,Loss:0.3280,Accuracy：0.9861\n",
      "Epoch:19000,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:19100,Loss:0.3280,Accuracy：0.9861\n",
      "Epoch:19200,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:19300,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:19400,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:19500,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:19600,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:19700,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:19800,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:19900,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:20000,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:20100,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:20200,Loss:0.3280,Accuracy：0.9864\n",
      "Epoch:20300,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:20400,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:20500,Loss:0.3280,Accuracy：0.9862\n",
      "Epoch:20600,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:20700,Loss:0.3279,Accuracy：0.9862\n",
      "Epoch:20800,Loss:0.3279,Accuracy：0.9864\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch:20900,Loss:0.3279,Accuracy：0.9862\n",
      "Epoch:21000,Loss:0.3279,Accuracy：0.9861\n",
      "Epoch:21100,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:21200,Loss:0.3279,Accuracy：0.9861\n",
      "Epoch:21300,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:21400,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:21500,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:21600,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:21700,Loss:0.3279,Accuracy：0.9864\n",
      "Epoch:21800,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:21900,Loss:0.3279,Accuracy：0.9864\n",
      "Epoch:22000,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:22100,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:22200,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:22300,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:22400,Loss:0.3279,Accuracy：0.9864\n",
      "Epoch:22500,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:22600,Loss:0.3279,Accuracy：0.9862\n",
      "Epoch:22700,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:22800,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:22900,Loss:0.3279,Accuracy：0.9863\n",
      "Epoch:23000,Loss:0.3279,Accuracy：0.9864\n",
      "Epoch:23100,Loss:0.3278,Accuracy：0.9863\n",
      "Epoch:23200,Loss:0.3278,Accuracy：0.9863\n",
      "Epoch:23300,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:23400,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:23500,Loss:0.3278,Accuracy：0.9863\n",
      "Epoch:23600,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:23700,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:23800,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:23900,Loss:0.3278,Accuracy：0.9863\n",
      "Epoch:24000,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24100,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24200,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24300,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24400,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24500,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24600,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24700,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24800,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:24900,Loss:0.3278,Accuracy：0.9864\n",
      "Epoch:25000,Loss:0.3278,Accuracy：0.9864\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import pandas_profiling as ppf\n",
    "# from tensorboardX import SummaryWriter\n",
    "from sklearn.model_selection import train_test_split\n",
    "# writer=SummaryWriter(logdir='./logistic_summary')\n",
    "\n",
    "ALL=pd.read_csv(r'./data/created_data/logistic_final.csv').reset_index(drop=True).set_index('ID')\n",
    "\n",
    "y=ALL['flag']\n",
    "train_X,val_X, train_y, val_y = train_test_split(ALL.drop(columns='flag'),y, test_size=0.30, random_state=0)\n",
    "\n",
    "class LR(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(LR,self).__init__()\n",
    "        self.fc=nn.Linear(12,2) # 由于27个维度已经固定了，所以这里写27\n",
    "    def forward(self,x):\n",
    "        x=self.fc(x)\n",
    "        out=torch.sigmoid(x)\n",
    "        return out\n",
    "\n",
    "\n",
    "def test(pred,lab):\n",
    "    t=pred.max(-1)[1]==lab\n",
    "    return torch.mean(t.float())\n",
    "\n",
    "\n",
    "def get_default_device():\n",
    "    \"\"\"Pick GPU if available, else CPU\"\"\"\n",
    "    if torch.cuda.is_available():\n",
    "        return torch.device('cuda')\n",
    "    else:\n",
    "        return torch.device('cpu')\n",
    "\n",
    "def to_device(data, device):\n",
    "    \"\"\"Move tensor(s) to chosen device\"\"\"\n",
    "    if isinstance(data, (list,tuple)):\n",
    "        return [to_device(x, device) for x in data]\n",
    "    return data.to(device, non_blocking=True)\n",
    "\n",
    "device = get_default_device()\n",
    "\n",
    "# 网络模型实例化\n",
    "net=LR()\n",
    "to_device(net, device)\n",
    "# 使用CrossEntropyLoss损失\n",
    "criterion=nn.CrossEntropyLoss() # BCEloss待测\n",
    "# 优化器\n",
    "optm=torch.optim.Adam(net.parameters(),lr=0.3) \n",
    "# 训练1500次\n",
    "epochs=25000\n",
    "\n",
    "\n",
    "for i in range(epochs):\n",
    "#      指定模型为训练模式，计算梯度\n",
    "    net.train()\n",
    "#      输入值都需要转化成torch的Tensor\n",
    "    x=to_device(torch.from_numpy(train_X.values).float(),device)\n",
    "    y=to_device(torch.from_numpy(train_y.values).long(),device)\n",
    "#     输入数据\n",
    "    y_hat=net(x)\n",
    "#     计算损失\n",
    "    loss=criterion(y_hat,y) \n",
    "#     前一步的损失清零\n",
    "    optm.zero_grad() \n",
    "#     反向传播 \n",
    "    loss.backward() \n",
    "#     更新参数\n",
    "    optm.step() \n",
    "#     writer.add_scalar('tra_loss',loss,i)\n",
    "\n",
    "#     if True:\n",
    "    if (i+1)%100 ==0 : # 这里我们每100次输出相关的信息\n",
    "#         指定模型为计算模式\n",
    "        net.eval()\n",
    "        test_in=to_device(torch.from_numpy(val_X.values).float(),device)\n",
    "        test_l=to_device(torch.from_numpy(val_y.values).long(),device)\n",
    "        test_out=net(test_in)\n",
    "#          使用我们的测试函数计算准确率\n",
    "        accu=test(test_out,test_l)\n",
    "#         writer.add_scalar('tes_loss',loss.item(),i)\n",
    "#         writer.add_scalar('tes_acc',accu,i)\n",
    "        print(\"Epoch:{},Loss:{:.4f},Accuracy：{:.4f}\".format(i+1,loss.item(),accu))    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OrderedDict([('fc.weight',\n",
       "              tensor([[ 7.3093e+00,  1.0684e+01, -1.1756e+01,  3.2961e+02, -2.7805e+01,\n",
       "                        7.7675e+02, -3.6712e+00,  7.8851e+00, -4.5155e+00, -7.9512e-01,\n",
       "                        4.1711e+00, -1.0358e+01],\n",
       "                      [-1.1238e+00,  3.6656e-01,  1.1861e+01, -1.0439e+02,  1.5735e+01,\n",
       "                       -9.0467e+02,  2.1425e+01, -2.6455e+00, -3.5045e-01,  1.7111e+01,\n",
       "                       -9.5384e+00,  1.1653e+01]], device='cuda:0')),\n",
       "             ('fc.bias', tensor([ 414.1797, -405.8227], device='cuda:0'))])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "net.state_dict()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 由逻辑回归输出特征权重"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "weights=[i if i > 0 else -i for i in [int(i) for i in (net.state_dict()['fc.weight'].cpu().numpy()[1]*10000)]]\n",
    "features=ALL.drop(columns='flag').columns.tolist()\n",
    "dic = dict(zip(features, weights))  # 词频以字典形式存储"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "features=['负债总额度','股权融资成本','股权融资额度','净利润','利润总额','纳税总额','内部融资和贸易融资成本','内部融资和贸易融资额度','所有者权益合计','营业总收入','债权融资成本','债权融资额度']\n",
    "dic = dict(zip(features, weights))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x396 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<wordcloud.wordcloud.WordCloud at 0x23a7b1843c8>"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from wordcloud import WordCloud, ImageColorGenerator\n",
    "import matplotlib.pyplot as plt\n",
    "from PIL import Image\n",
    "\n",
    "\n",
    "image = Image.open('./data/created_data/timg.jfif')  # 作为背景轮廓图\n",
    "graph = np.array(image)\n",
    "# 参数分别是指定字体、背景颜色、最大的词的大小、使用给定图作为背景形状\n",
    "wc = WordCloud(font_path='simkai.ttf', background_color='gray',max_words=2000,) #, mask=graph  \n",
    "wc.generate_from_frequencies(dic)  # 根据给定词频生成词云\n",
    "image_color = ImageColorGenerator(graph)\n",
    "plt.imshow(wc)\n",
    "plt.axis(\"off\")  # 不显示坐标轴\n",
    "plt.show()\n",
    "wc.to_file('./data/created_data/wordcloudgray.png')  # 图片命名\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ?WordCloud\n",
    "aaaa=[i for i in list(net.state_dict()['fc.weight'].cpu().numpy()[1])]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "di=dict(zip(features, aaaa))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'负债总额度': -1.1237559,\n",
       " '股权融资成本': 0.36655867,\n",
       " '股权融资额度': 11.861227,\n",
       " '净利润': -104.38966,\n",
       " '利润总额': 15.735193,\n",
       " '纳税总额': -904.6744,\n",
       " '内部融资和贸易融资成本': 21.4252,\n",
       " '内部融资和贸易融资额度': -2.6454968,\n",
       " '所有者权益合计': -0.35045236,\n",
       " '营业总收入': 17.110937,\n",
       " '债权融资成本': -9.538354,\n",
       " '债权融资额度': 11.653447}"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "di"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
